"""
@Author：十
@Time：2025/8/29 11:03
@FileName：details.py
@Description：点击表格后的单一接头数据展示弹窗
"""
import os
import sqlite3
import sys
import time
from datetime import datetime

from PyQt5.QtGui import QMouseEvent
from loguru import logger
import pyqtgraph as pg
from PyQt5.QtCore import QDateTime, QTime, Qt, QPoint, pyqtSignal, QRect, QPropertyAnimation
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout
from PyQt5 import QtWidgets


from UI.detail import Ui_Form
import resource.WTC_rc
from filter import FilterWindow


class DetailsWindow(QWidget, Ui_Form):
    Signal_refresh_interface = pyqtSignal()
    Signal_Get_filter_parameters = pyqtSignal(object)
    finished = pyqtSignal()

    def __init__(self):
        super(DetailsWindow, self).__init__()
        self.parameters = None
        self.sidebar_visible = False
        # 初始化鼠标拖拽相关变量
        self._tracking = False
        self._startPos = None
        self._endPos = None

        self.setupUi(self)

        # 主界面接收到数据时，向DetailsWindow发送信号，刷新界面
        self.Signal_refresh_interface.connect(self.refresh_data)

        self.pushButton_close.clicked.connect(self.close)

        self.Signal_Get_filter_parameters.connect(self.filter_parameters)

        # 呼出筛选边栏
        self.pushButton_Filter.clicked.connect(self.show_filterSidebar)
        self.sidebar = FilterWindow(self)
        self.sidebar.setGeometry(250, 0, -250, self.height())
        self.main_container = QWidget(self)
        self.main_container.setGeometry(0, 0, self.width(), self.height())

        # 将主界面内容移动到主容器中
        layout = QVBoxLayout(self.main_container)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.widget)

        self.initInterface()

    def resource_path(self, relative_path):
        """获取资源文件的绝对路径"""
        try:
            # PyInstaller创建临时文件夹，将路径存储在_MEIPASS中
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")

        return os.path.join(base_path, relative_path)

    def showWindow(self):
        self.show()

    # 初始化界面
    def initInterface(self):
        self.setWindowFlags(Qt.FramelessWindowHint)

        self.horizontalLayout.setContentsMargins(10, 10, 10, 10)

        # 时间选择器
        # 获取当前日期时间
        current_datetime = QDateTime.currentDateTime()

        # 提取当前日期部分
        current_date = current_datetime.date()

        # 创建时间对象，设置时间为23:59:00
        end_of_day_time = QTime(23, 59)

        # 组合日期和时间
        end_of_day_datetime = QDateTime(
            current_date,
            end_of_day_time
        )
        self.dateTimeEdit_End.setDateTime(end_of_day_datetime)
        self.dateTimeEdit_End.setMinimumDateTime(self.dateTimeEdit_Start.dateTime())
        self.dateTimeEdit_Start.dateTimeChanged.connect(lambda: self.dateTimeEdit_End.setMinimumDateTime(self.dateTimeEdit_Start.dateTime()))

        self.dateTimeEdit_Start.dateTimeChanged.connect(self.refresh_data)
        self.dateTimeEdit_End.dateTimeChanged.connect(self.refresh_data)

        # 事件筛选按钮不可见
        self.dateTimeEdit_End.setVisible(False)
        self.dateTimeEdit_Start.setVisible(False)

        # 动画设置
        self.sidebar_animation = QPropertyAnimation(self.sidebar, b"geometry")
        self.sidebar_animation.setDuration(300)

        self.container_animation = QPropertyAnimation(self.main_container, b"geometry")
        self.container_animation.setDuration(300)

    def filter_parameters(self, parameters):
        try:
            self.parameters = parameters
            self.refresh_data()
        except Exception as e:
            logger.critical(f'获取筛选参数错误：{e}')
            print('获取筛选参数错误:', e)

    def set_data(self, data):
        self.row_data = data
        sensor_id = self.row_data[1]

        temperature_dates = self.query_sensor_data(sensor_id)
        self.fill_data_table(temperature_dates)
        self.draw_line_chart(temperature_dates)

    # 定义刷新数据的函数
    def refresh_data(self):
        if hasattr(self, 'row_data'):
            sensor_id = self.row_data[1]
            temperature_dates = self.query_sensor_data(sensor_id)
            self.fill_data_table(temperature_dates)
            self.draw_line_chart(temperature_dates)

    # 查询传感器的所有数据
    def query_sensor_data(self, sensor_id):
        try:
            conn = sqlite3.connect(self.resource_path('db/WTC.db'))
            cursor = conn.cursor()
            start_time = self.dateTimeEdit_Start.dateTime().toString('yyyy-MM-dd hh:mm:ss')
            end_time = self.dateTimeEdit_End.dateTime().toString('yyyy-MM-dd hh:mm:ss')

            placeholders = ', '.join(['?'] * (len(self.parameters) - 8))

            select_sensor_data = f"""
            SELECT
                    temperature_db.inner_temperature,
                    temperature_db.external_temperature,
                    temperature_db.ambient_temps,
                    temperature_db.timestamp
                FROM device_db
                LEFT JOIN temperature_db ON device_db.sensor_id = temperature_db.sensor_id
                WHERE temperature_db.sensor_id = ?
                AND timestamp BETWEEN ? AND ?
                AND inner_temperature BETWEEN ? AND ?
                AND external_temperature BETWEEN ? AND ?
                AND ambient_temps BETWEEN ? AND ?
                AND state IN ({placeholders})
                ORDER BY temperature_db.timestamp
            """
            # print(select_sensor_data, (sensor_id, *self.parameters,))

            # select_sensor_data = """ SELECT inner_temperature, external_temperature, ambient_temps, timestamp FROM temperature_db WHERE sensor_id = ? AND timestamp between ? AND ?"""
            # cursor.execute(select_sensor_data, (sensor_id, start_time, end_time,))

            cursor.execute(select_sensor_data, (sensor_id, *self.parameters,))
            result = cursor.fetchall()

            # print(result)

            return result
        except Exception as e:
            logger.critical(f'获取传感器数据错误：{e}')
            print('获取传感器数据错误:', e)
        finally:
            if conn:
                conn.close()

    # 填充数据表格
    def fill_data_table(self, data):
        try:
            self.tableWidget.setRowCount(len(data))
            for i, row in enumerate(data):
                for j, value in enumerate(row):
                    item = QtWidgets.QTableWidgetItem(str(value))
                    item.setTextAlignment(Qt.AlignCenter)
                    self.tableWidget.setItem(i, j, item)
            self.tableWidget.setSortingEnabled(True)
        except Exception as e:
            logger.critical(f'填充数据展示表错误：{e}')
            print('填充数据展示表错误:', e)

    def draw_line_chart(self, data):
        try:
            self.line_View.clear()
            self.line_View.addLegend()

            timestamps = []
            external_temps = []
            internal_temps = []
            ambient_temps = []

            # 1. 根据表格显示
            if len(data) == 0:
                return

            # 2. 放在数组里
            for ext_temp, int_temp, ambient_temp, time_str in data:
                dt = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
                timestamp = time.mktime(dt.timetuple()) + dt.microsecond / 1e6

                if abs(ext_temp) < 100 and abs(int_temp) < 100:
                    timestamps.append(timestamp)
                    external_temps.append(ext_temp)
                    internal_temps.append(int_temp)
                    ambient_temps.append(ambient_temp)

                timestamps_str = [datetime.fromtimestamp(ts).strftime('%H:%M:%S') for ts in timestamps]

            # 3. 画图
            # 创建x轴标签字典
            ticks = [(ts, label) for ts, label in zip(timestamps, timestamps_str)]

            # 设置X轴格式化
            date_axis = pg.DateAxisItem(orientation='bottom')
            date_axis.setTicks([ticks])
            self.line_View.setAxisItems({'bottom': date_axis})

            # 绘制外部温度（红色线）
            self.external_plot = self.line_View.plot(timestamps, external_temps,
                                                     pen=pg.mkPen(color=(80, 135, 236), width=2),
                                                     symbol='o', symbolSize=6,
                                                     name="外部温度")

            # 绘制内部温度（蓝色线）
            self.internal_plot = self.line_View.plot(timestamps, internal_temps,
                                                     pen=pg.mkPen(color=(104, 187, 196), width=2),
                                                     symbol='s', symbolSize=6,
                                                     name="内部温度")

            self.ambient_plot = self.line_View.plot(timestamps, ambient_temps,
                                                    pen=pg.mkPen(color=(88, 165, 92), width=2),
                                                    symbol='s', symbolSize=6,
                                                    name="环境温度")

            # 添加网格
            self.line_View.showGrid(x=True, y=True, alpha=0.3)

            # 设置Y轴范围，留出空间
            min_temp = min(min(external_temps), min(internal_temps))
            max_temp = max(max(external_temps), max(internal_temps))
            self.line_View.setYRange(min_temp - 0.5, max_temp + 0.5)

            self.line_View.showGrid(x=True, y=True, alpha=0.3)

        except Exception as e:
            logger.critical(f'绘制折线图错误错误：{e}')

    def show_filterSidebar(self):
        try:
            sidebar_width = 400

            if self.sidebar_visible:
                # 隐藏侧边栏，主容器恢复原状
                self.sidebar_animation.setEndValue(QRect(-sidebar_width, 0, sidebar_width, self.height()))
                self.container_animation.setEndValue(QRect(0, 0, self.width(), self.height()))
            else:
                # 显示侧边栏，主容器向右移动
                self.sidebar_animation.setEndValue(QRect(0, 0, sidebar_width, self.height()))
                self.container_animation.setEndValue(QRect(sidebar_width, 0, self.width() - sidebar_width, self.height()))

            self.sidebar_visible = not self.sidebar_visible
            self.sidebar_animation.start()
            self.container_animation.start()
        except Exception as e:
            logger.critical(f'呼出筛选窗口错误：{e}')

    def mouseMoveEvent(self, e: QMouseEvent):
        if self._tracking:
            self._endPos = e.pos() - self._startPos
            self.move(self.pos() + self._endPos)

    def mousePressEvent(self, e: QMouseEvent):
        if e.button() == Qt.LeftButton:
            self._startPos = QPoint(e.x(), e.y())
            self._tracking = True

    def mouseReleaseEvent(self, e: QMouseEvent):
        if e.button() == Qt.LeftButton:
            self._tracking = False
            self._startPos = None
            self._endPos = None

    def closeEvent(self, event):
        self.finished.emit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = DetailsWindow()
    mainWindow.show()
    sys.exit(app.exec_())
